class Memory {
    ; 游戏内力值 [0x34, 0x98, 0x10, 0x7C]
    manaOffsetArr := [0x34, 0x98, 0x10, 0x7C]
    ; 剑灵基址 0x10910E4
    baseAddress := 0x10910E4
    __New(program := "Client.exe") {
        this.pid := this.getClientPID("ahk_exe " program)
        OutputDebug(this.pid)
        if !this.pid
            throw "获取进程ID失败！"
        this.hProcess := this.OpenProcess()
        this.manaBaseAddress := this.getBaseAddress()
    }
    __Delete() {
        if (this.hProcess)
            this.CloseHandle()
        ; OutputDebug("关闭句柄成功`n")
    }
    ;获取进程ID
    getClientPID(program) {
        try {
            pid := WinGetPID(program)
            return pid ? pid : 0
        } catch
            return 0
    }
    ;通过pid获取进程访问权限
    OpenProcess() {
        hProcess := DllCall('OpenProcess', 'UInt', 0x1F0FFF, 'Int', False, 'UInt', this.pid)
        if !hProcess
            throw "OpenProcess获取失败！"
        return hProcess
    }
    ;关闭打开的对象句柄
    CloseHandle() {
        if (DllCall("CloseHandle", "Ptr", this.hProcess))
            this.hProcess := 0
        else
            throw "CloseHandle关闭失败！"
    }
    ;读取内存数据
    read(baseAddress) {
        dwRead := 0
        if !DllCall('ReadProcessMemory', 'UInt', this.hProcess, 'UInt', BaseAddress, 'UIntP', &dwRead, 'UInt', 4, 'UIntP', 0) {
            throw "ReadProcessMemory读取失败！"
        } else
            return dwRead
    }
    ;读取指针偏移数据
    pointer(baseAddress, offsetArray) {
        lpBaseAddress := baseAddress
        for offset in offsetArray {
            try {
                baseAddress := this.readtoHex(lpBaseAddress)
            } catch as e {
                throw "读取指针偏移数据失败！" e.What()
            }
            lpBaseAddress := baseAddress + offset
        }
        ; return Format("{1:i}", this.read(baseAddress)) ;转换为十进制字符串
        return lpBaseAddress
    }
    ;转换为十六进制字符串
    readtoHex(baseAddress) => Format("{1:#x}", this.read(baseAddress))
    ;转换为十进制字符串
    readtoDEC(baseAddress) => Format("{1:i}", this.read(baseAddress))

    getBaseAddress() => this.pointer(this.baseAddress, this.manaOffsetArr)

    getMana() => this.readtoDEC(this.manaBaseAddress)


}